package com.yanyeori.framework.core.thread;

import com.alibaba.ttl.threadpool.TtlExecutors;
import com.yanyeori.framework.core.constant.BaseConstant;
import com.yanyeori.framework.core.constant.Cpu;
import com.yanyeori.framework.core.util.ThreadUtil;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;

import java.util.concurrent.*;

/**
 * 线程池配置
 */
@Configuration
public class ThreadPoolConfig implements AsyncConfigurer {

    @Bean(BaseConstant.TTL_EXECUTOR_SERVICE)
    public ExecutorService ttlExecutorService() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                Math.max(Cpu.PROCESSORS + 1, 20),
                Math.max(Cpu.PROCESSORS * 2, 100),
                60,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000),
                ThreadFactoryManager.namedThreadFactory("ttl"),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        return TtlExecutors.getTtlExecutorService(executor);
    }

    /**
     * 执行周期性或定时任务
     */
    @Bean(BaseConstant.TTL_SCHEDULED_EXECUTOR_SERVICE)
    protected ScheduledExecutorService ttlScheduledExecutorService() {
        ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(
                Cpu.PROCESSORS + 1,
                new BasicThreadFactory.Builder().namingPattern("ttl-schedule-pool-%d").daemon(true).build(),
                new ThreadPoolExecutor.CallerRunsPolicy()) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                ThreadUtil.printException(r, t);
            }
        };
        return TtlExecutors.getTtlScheduledExecutorService(executor);
    }

    @Override
    public Executor getAsyncExecutor() {
        return ttlExecutorService();
    }
}
